package com.info.zhiduoduo.pay.sdk.zhaoshangbank.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.gson.*;
import com.info.zhiduoduo.common.configs.ZhaoShangPayConfig;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.ImgBase64Util;
import com.info.zhiduoduo.common.utils.RandomUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.pay.formbean.zhaoshangbankpay.QueryTransactionInfoFormBean;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.HeadReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.HeadRespDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.RequestDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.common.ResponseDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.request.agentpay.QueryReceiptReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.request.agentpay.QueryTransactionInfoReqDTO;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.model.response.agentpay.*;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.DCHelper;
import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.HttpUtils;

import com.info.zhiduoduo.pay.sdk.zhaoshangbank.util.ZsPayUtil;
import com.info.zhiduoduo.repository.entity.pay.PaymentMerchant;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ZhaoShangBankPayApiService {

    @Resource
    ZhaoShangPayConfig zhaoShangPayConfig;

    @Value("${ZSElectronicReceiptPath}")
    private String electronicReceiptPath;

    public PayResDTO agentPay(JSONObject jsonObject, String userId){
        log.info("招商代付-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("招商代付-请求返回为空（网络异常）！");
            throw SmartException.of(StatusMsg.StatusMsg_472);
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("招商代付-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("招商代付-支付失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("招商代付-支付失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        //获取结果
        JSONArray value = body.getJSONArray("ntagcagcz1");
        return JSON.parseObject(value.getString(0), PayResDTO.class);
    }

    public TransactionOutlineResDTO queryTransactionOutline(JSONObject jsonObject, String userId, String tradeNo){
        log.info("查询招商交易概要结果-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商交易概要结果-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商交易概要结果-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商交易概要结果-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商交易概要结果-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        if (body.isEmpty()) {
            log.error("查询招商交易概要结果-查询失败！失败原因：body为空");
            return null;
        }
        //获取结果
        JSONArray value = body.getJSONArray("ntagcinqz");
        //遍历结果获取对应数据
        return ergodicResult(value,tradeNo);
    }

    private TransactionOutlineResDTO ergodicResult(JSONArray jsonArray, String tradeNo){
        if (null != jsonArray && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject object = jsonArray.getJSONObject(i);
                if (null != object && tradeNo.equals(object.getString("yurref"))) {
                    return JSON.parseObject(jsonArray.getString(i), TransactionOutlineResDTO.class);
                }
            }
        }
        return null;
    }

    public PayResultResDTO queryAgentPay(JSONObject jsonObject, String userId){
        log.info("查询招商代付结果-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商代付结果-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商代付结果-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商代付结果-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商代付结果-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        //获取结果
        JSONArray value = body.getJSONArray("ntagcinqz");
        return JSON.parseObject(value.getString(0), PayResultResDTO.class);
    }

    public PayDetailedDTO queryAgentPayDetailed(JSONObject jsonObject, String userId){
        log.info("查询招商代付明细-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商代付明细-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商代付明细-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商代付明细-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商代付明细-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        //获取结果
        JSONArray value = body.getJSONArray("ntagcdtly1");
        return JSON.parseObject(value.getString(0), PayDetailedDTO.class);
    }

    public RetreatDTO queryAgentPayRetreat(JSONObject jsonObject, String userId){
        log.info("查询招商退票明细-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商退票明细-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商退票明细-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商退票明细-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商退票明细-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        if (null != body && !body.isEmpty()) {
            //获取结果
            JSONArray value = body.getJSONArray("ntagdrfdz1");
            return JSON.parseObject(value.getString(0), RetreatDTO.class);
        }
        return null;
    }

    public AccountInfoResDTO queryAccountInfo(JSONObject jsonObject, String userId){
        log.info("查询招商账户信息-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商账户信息-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商账户信息-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商账户信息-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商账户信息-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        //获取结果
        JSONArray value = body.getJSONArray("ntqacinfz");
        return JSON.parseObject(value.getString(0), AccountInfoResDTO.class);
    }

    public TransactionCodeResDTO queryTransactionCode(JSONObject jsonObject, String userId){
        log.info("查询招商交易代码-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject,userId);
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商交易代码-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商交易代码-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if(null == head){
            log.error("查询招商交易代码-查询失败！失败原因：head为空");
            return null;
        }
        if(!"SUC0000".equals(head.getString("resultcode"))){
            log.error("查询招商交易代码-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        //获取body信息
        JSONObject body = response.getJSONObject("body");
        //获取结果
        JSONArray value = body.getJSONArray("ntagtls2z");
        return JSON.parseObject(value.getString(0), TransactionCodeResDTO.class);
    }

    /**
     * 账户交易信息查询,返回银行流水号
     */
    public String queryTransactionInfo(PaymentMerchant paymentMerchant,QueryTransactionInfoFormBean formBean) {
        //返回的银行流水号
        String reqnbr = null;
        //构建head信息
        HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryTransactionInfo(), paymentMerchant.getMerchantNo());

        //未传完标记 如为Y则表示查询交易日在本次查询完成后，还有数据未查，为N则表示已查完交易日的所有交易
        String cotflg;
        int trsseq = 0;
        do {
            //构建body
            QueryTransactionInfoReqDTO reqDTO = new QueryTransactionInfoReqDTO();
            reqDTO.setAccnbr(paymentMerchant.getBankCard());
            reqDTO.setBbknbr(paymentMerchant.getBranchNumber());
            reqDTO.setTrsdat(formBean.getTradeDate());
            reqDTO.setTrsseq(trsseq);

            RequestDTO<QueryTransactionInfoReqDTO> dto = new RequestDTO<>();
            dto.setHead(headReqDTO);
            dto.setBody(reqDTO);
            //请求对象转json
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("request", dto);

            //请求
            log.info("查询账户交易信息-请求对象：" + JSON.toJSONString(dto));
            String result = pushPost(jsonObject, paymentMerchant.getMerchantNo());
            if (StringUtil.isEmpty(result)) {
                log.error("查询账户交易信息-请求返回为空（网络异常）！");
                return null;
            }
            JSONObject object = JSON.parseObject(result);
            log.info("查询账户交易信息-请求返回结果:" + object.toString());

            ResponseDTO<TransactionInfoBodyResDTO> responseDTO = object.getObject("response", new TypeReference<ResponseDTO<TransactionInfoBodyResDTO>>() {
            });
            //获取head信息
            HeadRespDTO head = responseDTO.getHead();
            if (null == head) {
                log.error("查询账户交易信息-失败！失败原因：head为空");
                return null;
            }
            if (!"SUC0000".equals(head.getResultcode())) {
                log.error("查询账户交易信息-失败！失败原因：" + head.getResultmsg());
                return null;
            }
            //获取body信息
            TransactionInfoBodyResDTO body = responseDTO.getBody();
            if (null == body) {
                log.error("查询账户交易信息-失败！失败原因：body为空");
                break;
            }
            //获取结果
            List<TransactionInfoDetailResDTO> ntqactrsz2 = body.getNtqactrsz2();
            if (CollectionUtils.isEmpty(ntqactrsz2)) {
                return null;
            }
            for (TransactionInfoDetailResDTO detail : ntqactrsz2) {
                //找到对应的流水号，则返回对应的银行流水
                if (StringUtil.equals(detail.getYurref(), formBean.getTradeNo())) {
                    return detail.getRefnbr();
                }
            }

            // 设置续传值
            List<TransactionInfoAccResDTO> ntrbptrsz11 = body.getNtrbptrsz1();
            if (CollectionUtils.isNotEmpty(ntrbptrsz11)) {
                cotflg = ntrbptrsz11.get(0).getCotflg();
                trsseq = ntrbptrsz11.get(0).getTrsseq() + 1;
            } else {
                cotflg = "N";
            }

        } while (StringUtil.equals(cotflg, "Y"));

        return reqnbr;
    }

    /**
     * 查询招商单笔交易回单
     */
    public String queryElectronReceiptFile(PaymentMerchant paymentMerchant,String refnbr, String quedat, String tradeNo) {
        //构建head信息
        HeadReqDTO headReqDTO = HeadReqDTO.of(zhaoShangPayConfig.getQueryElectronReceipt(),paymentMerchant.getMerchantNo());
        //构建body
        QueryReceiptReqDTO reqDTO = new QueryReceiptReqDTO();
        reqDTO.setEacnbr(paymentMerchant.getBankCard());
        reqDTO.setTrsseq(refnbr);
        reqDTO.setQuedat(quedat);
        RequestDTO<QueryReceiptReqDTO> dto = new RequestDTO<>();
        dto.setHead(headReqDTO);
        dto.setBody(reqDTO);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("request",dto);

        log.info("查询招商单笔交易回单-请求对象：" + jsonObject.toJSONString());
        String result = pushPost(jsonObject, paymentMerchant.getMerchantNo());
        if (StringUtil.isEmpty(result)) {
            log.error("查询招商单笔交易回单-请求返回为空！");
            return null;
        }
        //将结果转为json
        JSONObject object = JSON.parseObject(result);
        log.info("查询招商单笔交易回单-请求返回结果:" + object.toString());
        JSONObject response = object.getJSONObject("response");
        //获取head信息
        JSONObject head = response.getJSONObject("head");
        if (null == head) {
            log.error("查询招商单笔交易回单-查询失败！失败原因：head为空");
            return null;
        }
        if (!"SUC0000".equals(head.getString("resultcode"))) {
            log.error("查询招商单笔交易回单-查询失败！失败原因：" + head.getString("resultmsg"));
            return null;
        }
        try {
            //获取body信息
            JSONObject body = response.getJSONObject("body");
            //生成pdf文件,文件路径+文件名称
            String pdfFilePath = electronicReceiptPath + File.separator + tradeNo + ".pdf";
            File file = ImgBase64Util.Base64ToImg(body.getString("fildat"), pdfFilePath);
            return file.getAbsolutePath();
        } catch (Exception e) {
            log.error("查询招商单笔交易回单-生成图片失败！失败原因：" + e.getMessage());
        }
        return null;
    }

    public String pushPost(JSONObject jsonObject, String UID) {
        // 发送请求
        try {
            String function = jsonObject.getJSONObject("request").getJSONObject("head").getString("funcode");
            String URL = zhaoShangPayConfig.getUrl();
            String bankpubkey = zhaoShangPayConfig.getBankPubKey();
            String privkey = zhaoShangPayConfig.getPrivkey();
            String sm4key = zhaoShangPayConfig.getSm4key();
            return ZsPayUtil.doProcess(new GsonBuilder().create().fromJson(jsonObject.toJSONString(), JsonObject.class), UID, URL, function, bankpubkey, privkey, sm4key);
        } catch (Exception e) {
            log.error("招商接口请求异常", e);
        }
        return null;
    }

//    public String pushPost(JSONObject jsonObject, String userId){
//        // 发送请求
//        HashMap<String, String> map = new HashMap<>();
//        map.put("UID", userId);
//        map.put("DATA", jsonObject.toJSONString());
//        try {
//            return HttpUtils.doPostForm(zhaoShangPayConfig.getUrl(), map);
//        } catch (Exception e) {
//            log.error("招商接口请求异常", e);
//        }
//        return null;
//    }
}
